package futbol.tacticas.concursantes.The1A;

import java.awt.Point;
import java.util.LinkedList;

import futbol.General;


public class BallBehaviour {
	//private LinkedList<Point> positions;
	private int speed;
	private double x, y, angle;
	private Point lastPos;
	private int catchable;
	
	public BallBehaviour(){
		//positions = new LinkedList<Point>();
		//positions.addLast(new Point(0,0));
		//trace = new Segment(new Point(0,0), new Point(0,0));
		speed = 0;
		lastPos = new Point(0,0);
		x = y = angle = 0d;
		catchable = -1;
		
	}
	
	public int getSpeed(){
		return speed;
	}
	
	public void setNewPosition(Point pos){

		Point endPoint = new Point();
		
		double minDist = 1000;
		double minAngle = 0;
		int minSpeed = 0;
			
		DoubleFor : for (int speed = 0; speed <= 21; ++speed){
			for (double angleTest = 0; angleTest < 2*Math.PI; angleTest+=Math.PI/100){
				double x = lastPos.getX();
				double y = lastPos.getY();
				double angle = angleTest;
				for (int n=0;n<speed && !isGoal(x,y);n++){
					x+=Math.cos(angle);
					y+=Math.sin(angle);
			        if (!isGoal(x,y)){
			            if (x>160){
			                x=320-x;  //160 - (x-160)
			                angle=General.corregirAngulo(Math.PI-angle);
			            }
			            if (x<-160){
			                x=-320-x; //-160 + (-160-x)
			                angle=General.corregirAngulo(Math.PI-angle);
			            }
			            if (y>120){
			                y=240-y; //120 - (x-120)
			                angle=General.corregirAngulo(-angle);
			            }
			            if (y<-120){
			                y=-240-y;  //-120 + (-120-x)
			                angle=General.corregirAngulo(-angle);
			            }
			        }
			        else{
			        	if (x < 0)
			        		x = -160;
			        	else
			        		x = 160;
			        	y = 0;	            		
			        }
			    } // for n
				
				endPoint.setLocation(x,y);				
				
				double dist = Utils.Distance(pos, endPoint);
				if (dist < minDist){
					minDist = dist;
					minSpeed = Math.max(speed - 1, 0);
					minAngle = angle;
					if (minDist == 0d)
						break DoubleFor;
				}
			} // for angle
		} // for speed
	        	
		this.angle = minAngle;
		this.speed = minSpeed;
		this.x = pos.getX();
		this.y = pos.getY();
		lastPos = (Point) pos.clone();
		
		/*
		trace = new Segment(positions.getFirst(),pos);
		boolean lineIsBroken = false;
		
		for (Point p : positions) {
			if (!trace.contains(p)){
				lineIsBroken = true;
				break;
			}
		}
		
		Point lastPos = positions.getLast();
		if (lineIsBroken)
		{
			positions.clear();
			if (Utils.Distance(lastPos, pos) < 30){
				positions.addLast(lastPos);
				trace = new Segment(positions.getFirst(),pos);
			}
			else
				lastPos = pos;
		}
		positions.addLast(pos);
		speed = (int) Math.round(Utils.Distance(lastPos, pos));
		x = pos.getX();
		y = pos.getY();
		angle=General.getAngulo(positions.getFirst().getX(),positions.getFirst().getY(),x,y);*/
	}
	
    public static boolean isGoal(double x, double y){
    	return (x>=160 && y>-30 && y<30) || (x<=-160 && y>-30 && y<30);
    }	
    
    public int getCatchable(){
    	return catchable;
    }
	
	public Point[] getShootPredictions(Point player, Point org, Point dest, double strength){
		Point[] res = new Point[30];
		double x = org.getX();
		double y = org.getY();    
		
		int nGrado=100;
        double nDis=General.getDistancia(player.getX(),player.getY(),dest.getX(),dest.getY());
        if (nDis<50) nGrado=(int)(nDis*2);        
        int nFuerza = (int) (strength*nGrado/100);    	
	
		double angle = General.getAngulo(x,y,dest.getX(),dest.getY());
		int speed = nFuerza*3;	
		this.catchable = speed - 14;
		
		res[0] = new Point();
		res[0].setLocation(x, y);	

		
		for (int i = 1; i < res.length; ++i){
	        for (int n=0;n<speed && !isGoal(x,y);n++){
	            x+=Math.cos(angle);
	            y+=Math.sin(angle);
	            if (!isGoal(x,y)){
	                if (x>160){
	                    x=320-x;  //160 - (x-160)
	                    angle=General.corregirAngulo(Math.PI-angle);
	                }
	                if (x<-160){
	                    x=-320-x; //-160 + (-160-x)
	                    angle=General.corregirAngulo(Math.PI-angle);
	                }
	                if (y>120){
	                    y=240-y; //120 - (x-120)
	                    angle=General.corregirAngulo(-angle);
	                }
	                if (y<-120){
	                    y=-240-y;  //-120 + (-120-x)
	                    angle=General.corregirAngulo(-angle);
	                }
	            }
	            else{
	            	if (x < 0)
	            		x = -160;
	            	else
	            		x = 160;
	            	y = 0;	            		
	            }
	        }
	        if (speed>0) 
	        	speed--;
	        
	        res[i] = new Point();
	        res[i].setLocation(x, y);
		}

		return res;
	}
	
	public Point[] getPredictions(){
		Point[] res = new Point[300];
		double x = this.x;
		double y = this.y;
		double angle = this.angle;
		int speed = this.speed;		
		res[0] = (Point) lastPos.clone();
        if (speed<15 || speed > 50)
        	catchable = 0;
        else
        	catchable = -1;
		
		for (int i = 1; i < res.length; ++i){
	        for (int n=0;n<speed && !isGoal(x,y);n++){
	            x+=Math.cos(angle);
	            y+=Math.sin(angle);
	            if (!isGoal(x,y)){
	                if (x>160){
	                    x=320-x;  //160 - (x-160)
	                    angle=General.corregirAngulo(Math.PI-angle);
	                }
	                if (x<-160){
	                    x=-320-x; //-160 + (-160-x)
	                    angle=General.corregirAngulo(Math.PI-angle);
	                }
	                if (y>120){
	                    y=240-y; //120 - (x-120)
	                    angle=General.corregirAngulo(-angle);
	                }
	                if (y<-120){
	                    y=-240-y;  //-120 + (-120-x)
	                    angle=General.corregirAngulo(-angle);
	                }
	            }
	        }
	        if (speed>0) 
	        	speed--;
	        if (speed<15 && catchable < 0)
	        	catchable = i;
	        
	        res[i] = new Point();
	        res[i].setLocation(x, y);
		}		
		if (catchable < 0)
			catchable = 0;		
		return res;
	}	
	
 
	
}
